﻿using AdminModels;
using Common;
using Entities;
using Entities.CoinEntities.BTCe;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace CoinModels.BTCe
{
    [JsonObject]
    public class BTCeCoinBase : iBasicCoinValues
    {
        private static string baseApiAddress = @"https://btc-e.com/api/2/";
        private static string callType = @"ticker";

        [JsonIgnore]
        public int? id { get; set; }

        [JsonProperty]
        public double high { get; set; }

        [JsonProperty]
        public double low { get; set; }

        [JsonProperty]
        public double avg { get; set; }

        [JsonProperty]
        public double vol { get; set; }

        [JsonProperty]
        public double vol_cur { get; set; }

        [JsonProperty]
        public double last { get; set; }

        [JsonProperty]
        public double buy { get; set; }

        [JsonProperty]
        public double sell { get; set; }

        [JsonIgnore]
        public DateTime? updatedat { get; set; }

        [JsonProperty]
        public int updated
        {
            set { updatedat = ConversionHelpers.ConvertUnixTimeStamp(value.ToString()); }
        }

        [JsonIgnore]
        public DateTime? servertimeat { get; set; }

        [JsonProperty]
        public int server_time
        {
            set { servertimeat = ConversionHelpers.ConvertUnixTimeStamp(value.ToString()); }
        }

        [JsonIgnore]
        public virtual string primarycode { get; set; }

        [JsonIgnore]
        public virtual string secondarycode { get; set; }

        private void SetCodes() { }

        public static BTCeCoinBase GetCoinModel(string primaryCode, string secondaryCode)
        {
            BTCeCoinBase model = null;
            BTCeEntity entity = null;

            using (AegirContext db = new AegirContext())
            {
                entity = db.BTCe_Coin.Where(btce => btce.primarycode == primaryCode
                    && btce.secondarycode == secondaryCode)
                    .OrderBy(btce => btce.updatedat).FirstOrDefault();
            }

            if (entity != null)
            {
                model.id = entity.id;
                model.high = entity.high;
                model.low = entity.low;
                model.avg = entity.avg;
                model.vol = entity.vol;
                model.vol_cur = entity.vol_cur;
                model.last = entity.last;
                model.buy = entity.buy;
                model.sell = entity.sell;
                model.updatedat = entity.updatedat;
                model.servertimeat = entity.servertimeat;
                model.primarycode = entity.primarycode;
                model.secondarycode = entity.secondarycode;
            }

            return model;
        }

        public static bool PersistCoinCollection(List<BTCeCoinBase> coinsToPersist)
        {
            bool success = false;
            Exception exc = null;

            using (AegirContext db = new AegirContext())
            {
                foreach (BTCeCoinBase item in coinsToPersist)
                {
                    item.updatedat = DateTime.Now;
                    db.BTCe_Coin.Add(ConvertToEntity(item));
                }
                try
                {
                    db.SaveChanges();
                    success = true;
                }
                catch (Exception ex)
                {
                    success = false;
                    exc = ex;
                }
            }

            if (exc != null)
                ErrorLog.SaveLog(exc, "BTCe.Coin", ErrorType.Persistance);

            return success;
        }

        private static BTCeEntity ConvertToEntity(BTCeCoinBase model)
        {
            BTCeEntity entity = new BTCeEntity();

            // TODO: Validation
            if (model.id != null)
                entity.id = model.id??0;
            entity.high = model.high;
            entity.low = model.low;
            entity.avg = model.avg;
            entity.vol = model.vol;
            entity.vol_cur = model.vol_cur;
            entity.last = model.last;
            entity.buy = model.buy;
            entity.sell = model.sell;
            entity.updatedat = model.updatedat;
            entity.servertimeat = model.servertimeat;
            entity.primarycode = model.primarycode;
            entity.secondarycode = model.secondarycode;

            return entity;
        }

        public static BTCeCoinBase ConvertToModel(BTCeEntity entity)
        {
            BTCeCoinBase model = new BTCeCoinBase();

            if (entity != null)
            {
                model.id = entity.id;
                model.high = entity.high;
                model.low = entity.low;
                model.avg = entity.avg;
                model.vol = entity.vol;
                model.vol_cur = entity.vol_cur;
                model.last = entity.last;
                model.buy = entity.buy;
                model.sell = entity.sell;
                model.updatedat = entity.updatedat;
                model.servertimeat = entity.servertimeat;
                model.primarycode = entity.primarycode;
                model.secondarycode = entity.secondarycode;
            }

            return model;
        }

        public BTCeCoinBase GetCoin()
        {
            BTCeCoinBase coin = null;

            HttpClient client = new HttpClient();
            string rateType = primarycode.ToLower() + "_" + secondarycode.ToLower() + "/";

            client.BaseAddress = new Uri(baseApiAddress);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = client.GetAsync(rateType + callType).Result;
            BTCeCoinWrapper generic;

            if (response.IsSuccessStatusCode)
            {
                var mydata = response.Content.ReadAsStringAsync().Result;
                JsonSerializerSettings settings = DefaultValues.GetJsonSettings();
                generic = JsonConvert.DeserializeObject<BTCeCoinWrapper>(mydata, settings);
                coin = generic.ticker;
                // Have to add the codes manually
                coin.primarycode = primarycode;
                coin.secondarycode = secondarycode;
            }
            else
            {
                throw new Exception(response.ReasonPhrase);
            }


            return coin;
        }

        public static Type[] TypeOfBTCeCoins = {
                                                   typeof(BTCeBTCUSD)
                                                   , typeof(BTCeBTCEUR)
                                               };
    }

    [JsonObject]
    public class BTCeCoinWrapper
    {
        [JsonProperty]
        public BTCeCoinBase ticker { get; set; }
    }
}
